package com.coolaid.tictactoe;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import android.os.AsyncTask;
import android.util.Log;

public class ClientSocket extends AsyncTask<Void, Integer, Void> {

	String ip;
	int port;
	Socket socket;
	BufferedReader inputStream;
	PrintStream outputStream;

	DataTransfer inputObject;

	UpdateTimer timer;

	public ClientSocket(String ip, int port, DataTransfer inputObject) {
		this.ip = ip;
		this.port = port;

		this.inputObject = inputObject;

		timer = new UpdateTimer();
		timer.init(this);
	}

	// This method initialises the whole client-server-connection. It updates
	// every 7 seconds, which might be changed.
	@Override
	protected Void doInBackground(Void... params) {
		ScheduledThreadPoolExecutor sch = (ScheduledThreadPoolExecutor) Executors
				.newScheduledThreadPool(0);
		ScheduledFuture<?> periodicFuture = sch.scheduleAtFixedRate(timer, 1, 15, TimeUnit.SECONDS);
		return null;
	}

	public void getConnection() {
		try {
			socket = new Socket(ip, port);
			socket.setSoTimeout(3000);

			inputStream = new BufferedReader(new InputStreamReader(
					socket.getInputStream()));
			outputStream = new PrintStream(socket.getOutputStream());
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			Log.d("TicTacToe", e.getLocalizedMessage());
		}

	}

	// method to update the connection with the server.
	public void updateStrings() {
		// sends text, if needed
		getConnection();
		if (inputObject.mustSend) {
			sendString(inputObject.toSend);
			inputObject.toSend = "";
			inputObject.mustSend = false;
		}

		// receive text..
		if (inputObject.canReceive) {
			try {
				inputObject.received = inputStream.readLine().toString();
				Log.d("TicTacToe", "Received!!! : " + inputObject.received);
				inputObject.canReceive = false;
			} catch (Exception e) {
				inputObject.received = "";
			}
		}
		if(inputObject.threadFinished){
			try {
				outputStream.println(0);
				socket.close();
				inputStream = null;
				outputStream = null;
			} catch (IOException e) {
				// TODO Auto-generated catch block
				Log.d("TicTacToe", e.getLocalizedMessage());
			}
		}
	}

	public void sendString(String string) {
		outputStream.println(string);
		Log.d("TicTacToe", "String Sent! " + string);
	}

	public void setTimerParent(StringSendReceive parent) {
		this.timer.setInterpreter(parent);
	}
}

class UpdateTimer implements Runnable {
	ClientSocket client;
	StringSendReceive stringInterpreter;

	@Override
	public void run() {
		client.updateStrings();
		if (stringInterpreter != null) {
			stringInterpreter.notifyByServer();
		}
		Log.d("TicTacToe", "Timer fired");

	}

	public void init(ClientSocket client) {
		this.client = client;
	}

	public void setInterpreter(StringSendReceive stringInterpreter) {
		this.stringInterpreter = stringInterpreter;
	}
}
